package edu.ntu.cloudroid.xacml;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import com.sun.xacml.PDP;
import com.sun.xacml.PDPConfig;
import com.sun.xacml.ctx.RequestCtx;
import com.sun.xacml.ctx.ResponseCtx;
import com.sun.xacml.finder.AttributeFinder;
import com.sun.xacml.finder.AttributeFinderModule;
import com.sun.xacml.finder.PolicyFinder;
import com.sun.xacml.finder.PolicyFinderModule;
import com.sun.xacml.finder.impl.CurrentEnvModule;
import com.sun.xacml.finder.impl.SelectorModule;

import edu.ntu.cloudroid.xacml.finder.ClouDroidPolicyFinderModule;

class ClouDroidPDP
{
   // this is the actual PDP object we'll use for evaluation
   private PDP pdp = null;

   private final ClouDroidPolicyFinderModule policyModule;

   public ClouDroidPDP()
   {
      // Set up our factories
      Utilities.setUpFactory();

      this.policyModule = new ClouDroidPolicyFinderModule();

      // Setup the PolicyFinder that this PDP will use
      PolicyFinder policyFinder = new PolicyFinder();
      Set<PolicyFinderModule> policyModules = new HashSet<PolicyFinderModule>();
      policyModules.add(policyModule);
      policyFinder.setModules(policyModules);

      // Set up the AttributeFinder instances
      CurrentEnvModule envAttributeModule = new CurrentEnvModule();
      SelectorModule selectorAttributeModule = new SelectorModule();

      List<AttributeFinderModule> attributeModules = new ArrayList<AttributeFinderModule>();
      attributeModules.add(envAttributeModule);
      attributeModules.add(selectorAttributeModule);

      AttributeFinder attributeFinder = new AttributeFinder();
      attributeFinder.setModules(attributeModules);

      // Finally, initialize our PDP
      pdp = new PDP(new PDPConfig(attributeFinder, policyFinder, null));
   }

   /**
    * Evaluates the given request and returns the Response that the PDP will
    * hand back to the PEP.
    * 
    * @param requestCtx
    *           the PDP request context
    * 
    * @return the result of the evaluation
    */
   public ResponseCtx evaluate(RequestCtx requestCtx)
   {
      return pdp.evaluate(requestCtx);
   }
}
